//
//  NSMutableArray.h
//  面试题
//
//  Created by Toj on 8/25/21.
//

http://blog.joyingx.me/2015/05/03/NSMutableArray%20原理揭露/
https://www.jianshu.com/p/bfa1dfff9ff0

#pragma mark - 问题
1. 数组有几种
2. NSMutableArray操作元素(inset/ add/ remove)底层思想

#pragma mark 数组有几种
1. 当元素为空时，返回的是__NSArray0的单例；
2. 当元素仅有一个时，返回的是__NSSingleObjectArrayI的实例
3. 当元素大于一个的时候，返回的是__NSArrayI的实例;
4. 可变数组, 返回的是__NSArrayM的实例;

#pragma mark - NSMutableArray操作元素(inset/ add/ remove)底层思想
#pragma mark 普通C的数组
1. 普通C的数组思想是:
remove: 会把index后面的元素提前
inset: 会把index后面的往后移动
add: 会在末尾处增加一个值

但是这样不符合面向对象的思想
#pragma mark NSMutableArray
2. NSMutableArray 就是利用环形缓冲区实现的元素(inset/ add/ remove)
所以oc里的数组是这样操作的 -> 环形缓冲区, 双向缓冲区
环形缓冲区: 保证移动最少个元素保证数据可连续性

// 底层代码结构
@interface __NSArrayM : NSMutableArray
{
    unsigned long long _used;
    unsigned long long _doHardRetain:1;
    unsigned long long _doWeakAccess:1;
    unsigned long long _size:62;
    unsigned long long _hasObjects:1;
    unsigned long long _hasStrongReferences:1;
    unsigned long long _offset:62;
    unsigned long long _mutations;
    id *_list;
}


除缓冲区满
删除: 会在删除index后, 移动最少的一边元素,
如果移动是头元素 offset 会偏移n位
size 保持不变
used 减少

增加: 会在空闲的(头/尾)位置增加元素
改变 used 值, 插入也是雷同
